import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold, StratifiedKFold
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import cohen_kappa_score

# 读入数据
import codecs

cardata= pd.read_csv('MTPLdata.csv')

# 数据信息
cardata.clm.value_counts()
cardata.clm.value_counts(normalize=True)
cardata.info()

# 哑变量处理-独热编码
cardata['clm'] = cardata['clm'].map(str)
X_raw = cardata[['age', 'ac', 'power', 'gas', 'brand', 'area', 'dens', 'ct']]
X = pd.get_dummies(X_raw)
y = cardata['clm']

# 训练集和测试集划分
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=20000, random_state=1)

# 分类树
model = DecisionTreeClassifier(max_depth=2, class_weight='balanced', random_state=123)
model.fit(X_train, y_train)
model.score(X_test, y_test)
plt.figure(figsize=(11, 11))
plot_tree(model, feature_names=X.columns, node_ids=True, rounded=True, precision=2)

pred = model.predict(X_test)
table = pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])
table

table = np.array(table)
Accuracy = (table[0, 0] + table[1, 1]) / np.sum(table)
Error_rate = 1 - Accuracy
Sensitivity = table[1, 1] / (table[1, 0] + table[1, 1])
Specificity = table[0, 0] / (table[0, 0] + table[0, 1])
Recall = table[1, 1] / (table[0, 1] + table[1, 1])

# 绘制总不纯度与ccp_alphas的图形
model = DecisionTreeClassifier(class_weight='balanced', random_state=123)
path = model.cost_complexity_pruning_path(X_train, y_train)

plt.plot(path.ccp_alphas, path.impurities, marker='o', drawstyle='steps-post')
plt.xlabel('alpha (cost-complexity parameter)')
plt.ylabel('Total Leaf Impurities')
plt.title('Total Leaf Impurities vs alpha for Training Set')

max(path.ccp_alphas), max(path.impurities)

# 通过交叉验证选择最佳ccp_alpha
rangeccpalpha = np.linspace(0.000001, 0.0001, 10, endpoint=True)
param_grid = {'ccp_alpha': rangeccpalpha}
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)
model = GridSearchCV(DecisionTreeClassifier(max_depth=3, class_weight='balanced', random_state=123), param_grid, cv=kfold)
model.fit(X_train, y_train)

model.best_params_
model = model.best_estimator_
model.score(X_test, y_test)
plt.figure(figsize=(11, 11))
plot_tree(model, feature_names=X.columns, node_ids=True, impurity=True, proportion=True, rounded=True, precision=3)

# 特征重要性
model.feature_importances_

sorted_index = model.feature_importances_.argsort()
plt.barh(range(X_train.shape[1]), model.feature_importances_[sorted_index])
plt.yticks(np.arange(X_train.shape[1]), X_train.columns[sorted_index])
plt.xlabel('Feature Importance')
plt.ylabel('Feature')
plt.title('Decision Tree')
plt.tight_layout()

# 预测性能
pred = model.predict(X_test)
table = pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])
table

table = np.array(table)
Accuracy = (table[0, 0] + table[1, 1]) / np.sum(table)
Sensitivity = table[1, 1] / (table[1, 0] + table[1, 1])
cohen_kappa_score(y_test, pred)

# 使用不同阈值进行预测
#prob_1 = prob[:, 1]
#pred_new = (prob_1 >= 0.1)

#table = pd.crosstab(y_test, pred_new, rownames=['Actual'], colnames=['Predicted'])
#table

#table = np.array(table)
#Accuracy = (table[0, 0] + table[1, 1]) / np.sum(table)
#Sensitivity = table[1, 1] / (table[1, 0] + table[1, 1])
# 使用熵准则
rangeccpalpha = np.linspace(0.000001, 0.0001, 10, endpoint=True)
param_grid = {'ccp_alpha': rangeccpalpha}
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)
model = GridSearchCV(DecisionTreeClassifier(criterion='entropy', random_state=123), param_grid, cv=kfold)

model.fit(X_train, y_train)
model.score(X_test, y_test)

pred = model.predict(X_test)
pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])
print("cardata.clm.value_counts():")
print(cardata.clm.value_counts())

print("cardata.clm.value_counts(normalize=True):")
print(cardata.clm.value_counts(normalize=True))

print("cardata.info():")
print(cardata.info())

print("model.score(X_test, y_test):")
print(model.score(X_test, y_test))

print("table:")
print(table)

print("Accuracy:")
print(Accuracy)

print("Error_rate:")
print(Error_rate)

print("Sensitivity:")
print(Sensitivity)

print("Specificity:")
print(Specificity)

print("Recall:")
print(Recall)

#print("model.cost_complexity_pruning_path(X_train, y_train):")
#print(model.cost_complexity_pruning_path(X_train, y_train))

print("plt.plot(path.ccp_alphas, path.impurities, marker='o', drawstyle='steps-post'):")
plt.plot(path.ccp_alphas, path.impurities, marker='o', drawstyle='steps-post')
plt.xlabel('alpha (cost-complexity parameter)')
plt.ylabel('Total Leaf Impurities')
plt.title('Total Leaf Impurities vs alpha for Training Set')
plt.show()

print("model.best_params_:")
print(model.best_params_)

print("model.score(X_test, y_test):")
print(model.score(X_test, y_test))

print("plot_tree(model, feature_names=X.columns, node_ids=True, impurity=True, proportion=True, rounded=True, precision=3):")
best_model = model.best_estimator_
plt.figure(figsize=(10, 10))
plot_tree(best_model, feature_names=X.columns, filled=True, rounded=True, precision=3)
plt.show()

print("model.feature_importances_:")
best_model = model.best_estimator_
feature_importances = best_model.feature_importances_
print(feature_importances)

print("plt.barh(range(X_train.shape[1]), model.feature_importances_[sorted_index]):")
best_model = model.best_estimator_
feature_importances = best_model.feature_importances_
sorted_index = np.argsort(feature_importances)

plt.barh(range(X_train.shape[1]), feature_importances[sorted_index])
plt.yticks(np.arange(X_train.shape[1]), X_train.columns[sorted_index])
plt.xlabel('Feature Importance')
plt.ylabel('Feature')
plt.title('Decision Tree Feature Importance')
plt.tight_layout()
plt.show()
print("table:")
print(table)

print("Accuracy:")
print(Accuracy)

print("Sensitivity:")
print(Sensitivity)

print("cohen_kappa_score(y_test, pred):")
print(cohen_kappa_score(y_test, pred))

print("pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted']):")
print(pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted']))